#pragma once
#include"Reactor.hpp"
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include "Log.hpp"
#include "Connection.hpp"

const static int BUFFERSIZE = 4096;
class HandlerConnection
{
public:
    HandlerConnection(Handler_t process)
        : _process(process)
    {
    }
    void HandlerRecver(Connection *conn)
    {
        errno = 0;
        while (true)
        {
            char buffer[BUFFERSIZE];
            int n = ::recv(conn->Sockfd(), buffer, sizeof(buffer) - 1, 0);
            if (n > 0)
            {
                buffer[n] = 0;
                conn->AppendInBuffer(buffer);
            }
            else
            {
                if (errno == EWOULDBLOCK)
                {
                    LOG(INFO, "数据读取完毕\n");
                    break;
                }
                else if (errno == EINTR)
                {
                    continue;
                }
                else
                {
                    LOG(INFO, "数据读取失败 ,进行异常处理\n");
                    conn->_handler_excepter(conn);
                    return;
                }
            }
        }
        std::cout << conn->Sockfd() << " inbuffer 内容: " << conn->InBuffer() << std::endl;

        _process(conn); // 内容分析
    }
    void HandlerSender(Connection *conn)
    {
        errno = 0;
        while (true)
        {
            int n = ::send(conn->Sockfd(), conn->OutBuffer().c_str(), conn->OutBuffer().size(), 0);
            if (n > 0)
            {
                conn->DiscardBuffer(n);
                if (conn->OutBuffer().empty())
                    break;
            }
            else
            {
                if (errno == EWOULDBLOCK) // 发送条件不满足
                {
                    break;
                }
                else if (errno == EINTR)
                {
                    continue;
                }
                else
                {
                    conn->_handler_excepter(conn);
                    return;
                }
            }
        }

        // 发送条件不满足&&发送缓冲区还有数据
        if (!conn->OutBuffer().empty())
        {
            // 开启对写事件的关心
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(), true, true);
        }
        else
        {
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(), true, false);
        }
    }
    void HandlerExcepter(Connection *conn)
    {
        // 整个代码的所有异常的逻辑处理 都在这里
        conn->_R->DelConnection(conn->Sockfd());
    }

private:
    Handler_t _process;
};